﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Bovril.PlayingCards.French;
using Bovril.Poker;

namespace Bovril.Poker.TestbedCL
{
    class Program
    {
        static void Main(string[] args)
        {
            Shuffle();

            HandRankTest();

            //ReconstructAnalyser();

            AnalyserTest();
        }

        static void Shuffle()
        {
            Deck deck = new Deck();
            deck.Shuffle();
            deck.Shuffle();
            deck.Shuffle();
            deck.Shuffle();
            deck.Shuffle();
        }

        static void HandRankTest()
        {
            Hand straightFlush1 = new Hand(
                new Card(RankValue.Seven, SuitValue.Clubs),
                new Card(RankValue.Nine, SuitValue.Clubs),
                new Card(RankValue.Ten, SuitValue.Clubs),
                new Card(RankValue.Jack, SuitValue.Clubs),
                new Card(RankValue.Eight, SuitValue.Clubs));
            Debug.Assert(straightFlush1.Category == HandCategory.StraightFlush);

            Hand fourOfAKind1 = new Hand(
                new Card(RankValue.Ace, SuitValue.Hearts),
                new Card(RankValue.Four, SuitValue.Clubs),
                new Card(RankValue.Four, SuitValue.Diamonds),
                new Card(RankValue.Four, SuitValue.Hearts),
                new Card(RankValue.Four, SuitValue.Spades));
            Debug.Assert(fourOfAKind1.Category == HandCategory.FourOfAKind);

            Hand fourOfAKind2 = new Hand(
                new Card(RankValue.Four, SuitValue.Diamonds),
                new Card(RankValue.Four, SuitValue.Clubs),
                new Card(RankValue.Ace, SuitValue.Hearts),
                new Card(RankValue.Four, SuitValue.Hearts),
                new Card(RankValue.Four, SuitValue.Spades));
            Debug.Assert(fourOfAKind2.Category == HandCategory.FourOfAKind);

            Hand fullHouse1 = new Hand(
                new Card(RankValue.Four, SuitValue.Diamonds),
                new Card(RankValue.Four, SuitValue.Clubs),
                new Card(RankValue.Eight, SuitValue.Hearts),
                new Card(RankValue.Four, SuitValue.Hearts),
                new Card(RankValue.Eight, SuitValue.Spades));
            Debug.Assert(fullHouse1.Category == HandCategory.FullHouse);

            Hand flush1 = new Hand(
                new Card(RankValue.Two, SuitValue.Hearts),
                new Card(RankValue.Five, SuitValue.Hearts),
                new Card(RankValue.Ten, SuitValue.Hearts),
                new Card(RankValue.Ace, SuitValue.Hearts),
                new Card(RankValue.Queen, SuitValue.Hearts));
            Debug.Assert(flush1.Category == HandCategory.Flush);

            Hand straight1 = new Hand(
                new Card(RankValue.Three, SuitValue.Hearts),
                new Card(RankValue.Seven, SuitValue.Spades),
                new Card(RankValue.Five, SuitValue.Clubs),
                new Card(RankValue.Six, SuitValue.Clubs),
                new Card(RankValue.Four, SuitValue.Clubs));
            Debug.Assert(straight1.Category == HandCategory.Straight);

            Hand straight2 = new Hand(
                new Card(RankValue.Two, SuitValue.Hearts),
                new Card(RankValue.Three, SuitValue.Spades),
                new Card(RankValue.Four, SuitValue.Clubs),
                new Card(RankValue.Five, SuitValue.Clubs),
                new Card(RankValue.Ace, SuitValue.Clubs));
            Debug.Assert(straight2.Category == HandCategory.Straight);

            Hand straight3 = new Hand(
                new Card(RankValue.King, SuitValue.Hearts),
                new Card(RankValue.Ace, SuitValue.Spades),
                new Card(RankValue.Ten, SuitValue.Clubs),
                new Card(RankValue.Jack, SuitValue.Clubs),
                new Card(RankValue.Queen, SuitValue.Clubs));
            Debug.Assert(straight3.Category == HandCategory.Straight);

            Hand threeOfAKind0 = new Hand(
                new Card(RankValue.Queen, SuitValue.Spades),
                new Card(RankValue.Two, SuitValue.Spades),
                new Card(RankValue.Three, SuitValue.Clubs),
                new Card(RankValue.Three, SuitValue.Hearts),
                new Card(RankValue.Three, SuitValue.Diamonds));
            Debug.Assert(threeOfAKind0.Category == HandCategory.ThreeOfAKind);

            Hand twoPairs0 = new Hand(
                new Card(RankValue.Nine, SuitValue.Hearts),
                new Card(RankValue.Jack, SuitValue.Hearts),
                new Card(RankValue.Nine, SuitValue.Diamonds),
                new Card(RankValue.King, SuitValue.Spades),
                new Card(RankValue.King, SuitValue.Clubs));
            Debug.Assert(twoPairs0.Category == HandCategory.TwoPairs);

            Hand onePair0 = new Hand(
                new Card(RankValue.Six, SuitValue.Clubs),
                new Card(RankValue.Seven, SuitValue.Hearts),
                new Card(RankValue.Queen, SuitValue.Hearts),
                new Card(RankValue.Two, SuitValue.Hearts),
                new Card(RankValue.Two, SuitValue.Diamonds));
            Debug.Assert(onePair0.Category == HandCategory.OnePair);

            Hand nowt0 = new Hand(
                new Card(RankValue.Ace, SuitValue.Clubs),
                new Card(RankValue.Jack, SuitValue.Hearts),
                new Card(RankValue.Ten, SuitValue.Hearts),
                new Card(RankValue.Seven, SuitValue.Hearts),
                new Card(RankValue.Four, SuitValue.Diamonds));
            Debug.Assert(nowt0.Category == HandCategory.Nowt);
        }

        static void ReconstructAnalyser()
        {
            String myDocumentsDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            String holdEmDataPathname = Path.Combine(myDocumentsDirectory, "HoldEm.dat");
            if(File.Exists(holdEmDataPathname))
                File.Delete(holdEmDataPathname);
            HoldEmAnalyser holdEmAnalyser = HoldEmAnalyser.Load(holdEmDataPathname);

            holdEmAnalyser.Save(holdEmDataPathname);
        }

        static void AnalyserTest()
        {
            String myDocumentsDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            String holdEmDataPathname = Path.Combine(myDocumentsDirectory, "HoldEm.dat");
            HoldEmAnalyser holdEmAnalyser = HoldEmAnalyser.Load(holdEmDataPathname);

            Hole hole = new Hole(new Card(RankValue.Ten, SuitValue.Clubs), new Card(RankValue.Queen, SuitValue.Diamonds));
            Flop flop = new Flop(new Card(RankValue.King, SuitValue.Clubs), new Card(RankValue.Jack, SuitValue.Hearts), new Card(RankValue.Nine, SuitValue.Spades));
            double percentile = holdEmAnalyser.GetHoleFlopPercentile(hole, flop);
            Console.WriteLine(percentile.ToString("0.00"));

            hole = new Hole(new Card(RankValue.Ten, SuitValue.Clubs), new Card(RankValue.Three, SuitValue.Diamonds));
            Turn turn = new Turn(
                new Card(RankValue.King, SuitValue.Clubs), 
                new Card(RankValue.Jack, SuitValue.Hearts), 
                new Card(RankValue.Nine, SuitValue.Spades),
                new Card(RankValue.Three, SuitValue.Clubs));
            percentile = holdEmAnalyser.GetHoleTurnPercentile(hole, turn);
            Console.WriteLine(percentile.ToString("0.00"));

            hole = new Hole(new Card(RankValue.Ten, SuitValue.Clubs), new Card(RankValue.Two, SuitValue.Diamonds));
            River river = new River(
                new Card(RankValue.King, SuitValue.Clubs),
                new Card(RankValue.Jack, SuitValue.Hearts),
                new Card(RankValue.Nine, SuitValue.Spades),
                new Card(RankValue.Three, SuitValue.Clubs),
                new Card(RankValue.Five, SuitValue.Diamonds));
            percentile = holdEmAnalyser.GetHoleRiverPercentile(hole, river);
            Console.WriteLine(percentile.ToString("0.00"));

            holdEmAnalyser.Save(holdEmDataPathname);
        }
    }
}
